package cz.muni.fi.pa165.dundd.serviceImpl;

import cz.muni.fi.pa165.dundd.assembler.Assembler;
import cz.muni.fi.pa165.dundd.dao.AdministratorDAO;
import cz.muni.fi.pa165.dundd.dto.AdministratorDTO;
import cz.muni.fi.pa165.dundd.entity.Administrator;
import cz.muni.fi.pa165.dundd.service.AdministratorService;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author xceluch
 */
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class AdministratorServiceImpl implements AdministratorService, UserDetailsService {

    @Autowired
    private AdministratorDAO adminDAO;

    public void setAdministratorDAO(AdministratorDAO adminDAO) {
        this.adminDAO = adminDAO;
    }

    @Override
    public void createAdministrator(AdministratorDTO adminDTO) {
        adminDAO.createAdministrator(Assembler.administratorDtoToEntity(adminDTO));
    }

    @Override
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public void updateAdministrator(AdministratorDTO admin) {
        adminDAO.updateAdministrator(Assembler.administratorDtoToEntity(admin));
    }

    @Override
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public void deleteAdministrator(AdministratorDTO admin) {
        adminDAO.deleteAdministrator(Assembler.administratorDtoToEntity(admin));
    }

    @Override
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public List<AdministratorDTO> retrieveAllAdministrators() {
        List<AdministratorDTO> allAdminsDTO = new ArrayList();
        List<Administrator> allAdmins = adminDAO.retrieveAllAdministrators();

        for (Administrator administrator : allAdmins) {
            allAdminsDTO.add(Assembler.administratorEntityToDTO(administrator));
        }
        return allAdminsDTO;
    }

    @Override
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public AdministratorDTO retrieveAdministratorById(Long id) {
        Administrator admin = adminDAO.retrieveAdministratorById(id);
        return Assembler.administratorEntityToDTO(admin);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (username == null || username.isEmpty()) {
            return null;
        }

        AdministratorDTO dto = retrieveAdministrator(username);
        Administrator admin = Assembler.administratorDtoToEntity(dto);
        if (admin == null) {
            return null;
        }
        GrantedAuthority grantedAuth = new AdministratorGrantedAuthority(admin.getAuthority());
        AdministratorLoginDetails returnedAdminLD = 
                new AdministratorLoginDetails(admin.getId(), admin.getName(), admin.getPassword(),
                new GrantedAuthority[]{grantedAuth});
        return returnedAdminLD;
    }

    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    private AdministratorDTO retrieveAdministrator(String username) {
        try {
            AdministratorDTO adminDto = Assembler.administratorEntityToDTO(adminDAO.retrieveAdministrator(username));
            return adminDto;
        } catch (Exception ex) {
            return null;
        }
    }
}
